<?php
function apf_error_handler($errno, $errstr, $errfile, $errline) {
    if (($errno & error_reporting()) != 0) {

        $level_names = array(
            E_ERROR => 'E_ERROR', E_WARNING => 'E_WARNING',
            E_PARSE => 'E_PARSE', E_NOTICE => 'E_NOTICE',
            E_CORE_ERROR => 'E_CORE_ERROR', E_CORE_WARNING => 'E_CORE_WARNING',
            E_COMPILE_ERROR => 'E_COMPILE_ERROR', E_COMPILE_WARNING => 'E_COMPILE_WARNING',
            E_USER_ERROR => 'E_USER_ERROR', E_USER_WARNING => 'E_USER_WARNING',
            E_USER_NOTICE => 'E_USER_NOTICE' );
        if (defined('E_STRICT')) {
            $level_names[E_STRICT]='E_STRICT';
        }
        $levels=array();
        $value=$errno;
        if (($value&E_ALL)==E_ALL) {
            $levels[]='E_ALL';
            $value&=~E_ALL;
        }
        foreach($level_names as $level=>$name) {
            if(($value&$level)==$level) $levels[]=$name;
        }

        /*
        ob_start();
        debug_print_backtrace();
        $trace = ob_get_contents();
        ob_end_clean();
        $trace = preg_replace('/[\r\n]/', '; ', $trace);
        */

        $a = debug_backtrace(false);
        //出错时的url
        $error_url = @$_SERVER['REQUEST_URI'];
        $http_host = @$_SERVER['HTTP_HOST'];
        $trace="error_url:{$http_host}{$error_url};";
        foreach ($a as $b) {
            if (isset($b['file']) && isset($b['line'])) {
                $trace .= "{$b['file']}:#{$b['line']}; ";
            }
        }

        $apf = APF::get_instance();
        if ($apf->get_config('display_error')) {
            echo implode(' | ',$levels), " ". $errstr, ", TRACE: " ,$trace;
        }
        $logger = $apf->get_logger();
        $logger->warn("error_handler", implode(' | ',$levels), " ". $errstr, ", TRACE: " ,$trace);
    }
    return TRUE;
}

function apf_exception_handler($exception) {
    $logger = APF::get_instance()->get_logger();
    $logger->warn("apf_exception_handler", $exception);
    return TRUE;
}

function apf_require_file($file, $prefix="lib") {
    global $G_LOAD_PATH;
    if (defined('CACHE_PATH') && $prefix != "lib") {
        $f = apf_class_to_cache_file($file,$prefix);
        if (file_exists($f)) {
            if (!apf_required_files($file,$prefix)) {
                require_once "$f";
            }
            return true;
        }
    }
    foreach ($G_LOAD_PATH as $path) {
        if (file_exists("$path$prefix/$file")) {
            if (!defined('CACHE_PATH') || !apf_required_files($file,$prefix)) {
                require_once("$path$prefix/$file");
                if (defined('CACHE_PATH') && $prefix != "lib") {
                    apf_save_to_cache($file,$prefix,"$path$prefix/$file");
                }
            }
            return true;
        }
    }
    return false;
}

function apf_required_files ($file,$prefix) {
    global $cached_files;
    $f = $prefix . "/" . $file;
    if (in_array($f,$cached_files)) {
        return true;
    } else {
        $cached_files[] = $f;
    }
    return false;
}

function apf_file_cache_exist ($file,$prefix) {
    $dest_file = apf_class_to_cache_file($file,$prefix);
    if (file_exists($dest_file)) {
        return $dest_file;
    } else {
        return false;
    }
}

function apf_class_to_cache_file ($file,$prefix) {
    return CACHE_PATH . $prefix . "/" . $file;
}

function apf_save_to_cache ($file,$prefix,$source) {
    $dest_file = apf_class_to_cache_file($file,$prefix);
    if (file_exists($dest_file)) {
        return ;
    }
    $dir = dirname($dest_file);
    if (!is_dir($dir)) {
        @mkdir($dir,0775,TRUE);
    }
    //$txt = @php_strip_whitespace($source);
    file_put_contents($dest_file,@php_strip_whitespace($source));
}
function apf_require_class($class, $prefix="classes" , $firelog = true) {
    $file = apf_classname_to_filename($class);
    if (!apf_require_file("$file.php", $prefix)) {
        if ($firelog) {
            $logger = APF::get_instance()->get_logger();
            $logger->error("'$prefix/$class' not found");
            //add by jackie for more error infomation
            ob_start();
            debug_print_backtrace();
            $trace = ob_get_contents();
            ob_end_clean();
            $logger->error($trace);
        }
        return false;
    }
    return true;
}

function apf_require_controller($class, $firelog=true) {
    return apf_require_class($class, "controller" , $firelog);
}

function apf_require_interceptor($class) {
    return apf_require_class($class, "interceptor");
}

function apf_require_component($class) {
    return apf_require_class($class, "component");
}

function apf_require_page($class) {
    return apf_require_class($class, "page");
}

/**
 * @param string $class Class name
 * @return string Relative path
 */
function apf_classname_to_path($class) {
    $paths = split("_", $class);
    $count = count($paths) - 1;
    $path = "";
    for ($i = 0; $i < $count; $i++) {
        $path .= strtolower($paths[$i]) . "/";
    }
    return $path;
}

/**
 * @param string $class Class name
 * @return string Relative path
 */
function apf_classname_to_filename($class) {
    $paths = split("_", $class);
    $count = count($paths) - 1;
    $path = "";
    for ($i = 0; $i < $count; $i++) {
        $path .= strtolower($paths[$i]) . "/";
    }
    $class = $paths[$count];
    return "$path$class";
}
//
/*
function __autoload ($classname) {
    $matches = array();
    if (preg_match('/(.+)controller$/i',$classname,$matches)) {
        apf_require_class($matches[1],'controller');
    } else if (preg_match('/(.+)page$/i',$classname,$matches)) {
        apf_require_class($matches[1],'page');
    } else  if (preg_match('/(.+)component$/i',$classname,$matches)) {
        apf_require_class($matches[1],'component');
    } else {
        apf_require_class($classname);
    }
}
*/

